﻿using System.IO;
using System;
using LogNaga.Configuration;

namespace LogNaga.Logs
{
	/// <summary>
	/// 记录到文本文件
	/// </summary>
	/// <remarks>
	/// 注意,这个不是线程安全的
	/// </remarks>
	public class FileLog : TextWriterLog
	{
		private static readonly string basePath = AppDomain.CurrentDomain.BaseDirectory;

		#region .ctor

		/// <summary>
		/// 初始化FileLog实例
		/// </summary>
		/// <param name="filePath">文件名</param>
		/// <remarks>log存储路径是在程序的上一级</remarks>
		public FileLog(string fileName)
			: this(fileName, true)
		{
		}

		/// <summary>
		/// 初始化FileLog实例
		/// </summary>
		/// <param name="filePath">文件位置</param>
		/// <param name="isAppend">True表示追加，否则表示覆写</param>
		public FileLog(string fileName, bool isAppend)
			: this(fileName, isAppend, ExceptionFormatterHelper.Default)
		{
		}

		/// <summary>
		/// 初始化FileLog实例
		/// </summary>
		/// <param name="filePath">文件位置</param>
		/// <param name="isAppend">True表示追加，否则表示覆写</param>
		public FileLog(string fileName, bool isAppend, ExceptionFormatter exceptionFormatter)
			:base(CreateWriter(fileName, isAppend), true, exceptionFormatter)
		{
		}

		#endregion

		/// <summary>
		/// 创建一个TextWriter
		/// </summary>
		/// <param name="fileName">log文件名</param>
		/// <param name="isAppend">True表示追加，否则表示覆写</param>
		/// <returns>返回创建的<see cref="TextWriter"/></returns>
		private static TextWriter CreateWriter(string fileName, bool isAppend)
		{
			var path = Path.Combine(basePath, LoggingConfigurationSection.GetConfig().DirectoryName);
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
			}

			if (!fileName.EndsWith(".log", System.StringComparison.InvariantCultureIgnoreCase))
			{
				fileName += "_" + DateTime.Now.ToString("yyyyMM-dd-hh-mmss") + ".log";
			}

			fileName = Path.Combine(path, fileName);
			FileInfo info = new FileInfo(fileName);
			FileStream result;
			if (isAppend)
			{
				result = info.Open(FileMode.Append, FileAccess.Write, FileShare.Read);
			}
			else
			{
				result = info.Exists ? //如果存在
					info.Open(FileMode.Truncate, FileAccess.Write, FileShare.Read) : //覆写
					info.Open(FileMode.CreateNew, FileAccess.Write, FileShare.Read); //追加
			}

			return new StreamWriter(result);
		}
	}
}
